package cloud.seri.iot.aliyun.service


import cloud.seri.iot.aliyun.service.mapper.DeviceRequestMapper
import cloud.seri.iot.common.api.DeviceManager
import cloud.seri.iot.common.model.DeviceDTO
import cloud.seri.iot.common.model.DevicesDTO
import cloud.seri.iot.common.model.QueryDeviceDTO
import cloud.seri.iot.common.model.RegisterDevice
import com.aliyuncs.DefaultAcsClient
import com.aliyuncs.exceptions.ClientException
import com.aliyuncs.iot.model.v20180120.*
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service

@Service
class DeviceManagerService(private val client: DefaultAcsClient, private val requestMapper: DeviceRequestMapper) : DeviceManager
{
    /**
     * 注册设备
     *
     * @param pk         产品名称  必须
     * @param DeviceName            设备命名  非必须
     * @return 产品创建信息
     */
    override fun registerDevice(dto: RegisterDevice): RegisterDeviceResponse?
    {
        return client.getAcsResponse(requestMapper.getRegisterDeviceRequest(dto))
    }

    /**
     * 查询指定产品下的所有设备列表。
     *
     * @param pk         产品名称  必须
     * @param PageSize            设备命名  非必须
     * @param CurrentPage            设备命名  非必须
     * @return 产品创建信息
     */
    override fun queryDevice(dto: QueryDeviceDTO): QueryDeviceResponse?
    {
        return client.getAcsResponse(requestMapper.getQueryDeviceRequest(dto))
    }

    /**
     * 批量注册多个设备
     *
     * @param pk       产品名称  必须
     * @param Count       设备的数量 必须
     *
     * @Des 描述：
     */
    override fun batchRegisterDevice(pk: String, count: Int?): BatchRegisterDeviceResponse?
    {
        return client.getAcsResponse(BatchRegisterDeviceRequest().apply {
            productKey = pk
            this.count = count
        })
    }

    /**
     * 在指定产品下批量自定义设备名称
     *
     * @param pk       产品名称  非必须
     * @param DeviceNames       设备的名称  非必须
     * 描述：
     * 该接口需要和BatchRegisterDeviceWithApplyId接口结合使用，实现在一个产品下批量注册（即新建）
     * 多个设备，并且为每个设备单独命名。单次调用，最多能传入1,000 个设备名称。
     */
    override fun batchCheckDeviceNames(pk: String, DeviceNames: List<String>): BatchCheckDeviceNamesResponse?
    {
        return client.getAcsResponse(BatchCheckDeviceNamesRequest().apply {
            productKey = pk
            deviceNames = DeviceNames
        })
    }

    /**
     * 根据申请批次ID（ApplyId）批量注册设备
     *
     * @param pk       产品名称  必须
     * @param ApplyId       要批量注册的设备的申请批次ID。申请批次ID由调用BatchCheckDeviceNames接口返回。  必须
     *
     * @Des 描述：
     * 该接口需要和BatchCheckDeviceNames接口结合使用，实现在一个产品下批量注册（即新建）多个设备，并且为每个设备单独命名。
     */
    override fun batchRegisterDeviceWithApplyId(pk: String, ApplyId: Long?): BatchRegisterDeviceWithApplyIdResponse?
    {
        return client.getAcsResponse(BatchRegisterDeviceWithApplyIdRequest().apply {
            productKey = pk
            applyId = ApplyId
        })
    }

    /**
     * 查询批量注册设备申请的处理状态和结果
     *
     * @param pk       产品名称  必须
     * @param ApplyId       设备的数量 必须
     *
     * @Des 描述：
     */
    override fun queryBatchRegisterDeviceStatus(pk: String, ApplyId: Long?): QueryBatchRegisterDeviceStatusResponse?
    {
        return client.getAcsResponse(QueryBatchRegisterDeviceStatusRequest().apply {
            productKey = pk
            applyId = ApplyId
        })
    }

    /**
     * 查询批量注册的设备信息
     *
     * @param ApplyId       产品名称  必须
     * @param PageSize         必须
     * @param CurrentPage             必须
     *
     * @Des 描述：
     */
    override fun queryPageByApplyId(ApplyId: Long?, PageSize: Int?, CurrentPage: Int?): QueryPageByApplyIdResponse?
    {
        return client.getAcsResponse(QueryPageByApplyIdRequest().apply {
            applyId = ApplyId
            pageSize = PageSize
            currentPage = CurrentPage
        })
    }

    /**
     * 查看指定设备的运行状态
     *
     * @param pk       产品名称  非必须
     * @param DeviceName       设备的名称  非必须
     * @param IotId            设备ID    非必须
     * @return 产品创建信息
     */
    override fun getDeviceStatus(pk: String, DeviceName: String?, IotId: String?): GetDeviceStatusResponse?
    {
        return client.getAcsResponse(GetDeviceStatusRequest().apply {
            productKey = pk
            deviceName = DeviceName
            iotId = IotId
        })
    }

    /**
     * 批量查看指定设备的运行状态
     *
     * @param pk       产品名称  非必须
     * @param DeviceNames       设备的名称  非必须
     * @return 产品创建信息
     */
    override fun batchGetDeviceState(pk: String, DeviceNames: List<String>): BatchGetDeviceStateResponse?
    {
        return client.getAcsResponse(BatchGetDeviceStateRequest().apply {
            productKey = pk
            deviceNames = DeviceNames
        })
    }

    private val log = LoggerFactory.getLogger(DeviceManagerService::class.java)


    /**
     * 查询指定设备的详细信息
     * @param dto QueryDeviceDetailDTO
     * @return QueryDeviceDetailResponse
     * @throws ClientException
     */
    @Throws(ClientException::class)
    override fun queryDeviceDetail(dto: DeviceDTO): QueryDeviceDetailResponse
    {
        return client.getAcsResponse(requestMapper.getQueryDeviceDetailRequest(dto))
    }

    /**
     * 删除指定设备
     * @param dto DeviceDTO
     * @return DeleteDeviceResponse
     * @throws ClientException
     */
    @Throws(ClientException::class)
    override fun deleteDevice(dto: DeviceDTO): DeleteDeviceResponse
    {
        return client.getAcsResponse(requestMapper.getDeleteDevice(dto))
    }

    /**
     * 查看指定设备的运行状态。
     * @param dto DeviceDTO
     * @return GetDeviceStatusResponse?
     * @throws ClientException
     */
    @Throws(ClientException::class)
    fun getDeviceStatus(dto: DeviceDTO): GetDeviceStatusResponse?
    {
        return client.getAcsResponse(requestMapper.getDeviceStatusRequest(dto))
    }

    /**
     * 批量查看同一产品下指定设备的运行状态。
     * @param dto BatchGetDeviceStateRequestDTO
     * @return BatchGetDeviceStateResponse?
     * @throws ClientException
     */
    @Throws(ClientException::class)
    fun batchGetDeviceState(dto: DevicesDTO): BatchGetDeviceStateResponse?
    {
        return client.getAcsResponse(requestMapper.batchGetDeviceStateRequest(dto))
    }

    /**
     * 禁用指定设备
     * @param dto DeviceDTO
     * @return DisableThingResponse?
     * @throws ClientException
     */
    @Throws(ClientException::class)
    override fun disableThing(dto: DeviceDTO): DisableThingResponse?
    {
        return client.getAcsResponse(requestMapper.getDisableThinRequest(dto))
    }

    /**
     * 解除指定设备的禁用状态，即启用被禁用的设备。
     * @param dto DeviceDTO
     * @return EnableThingResponse?
     * @throws ClientException
     */
    @Throws(ClientException::class)
    override fun enableThing(dto: DeviceDTO): EnableThingResponse?
    {
        return client.getAcsResponse(requestMapper.getEnableThingRequest(dto))
    }

    /**
     * 查询设备统计数据。
     * @param pk String
     * @return QueryDeviceStatisticsResponse?
     * @throws ClientException
     */
    @Throws(ClientException::class)
    override fun queryDeviceStatistics(pk: String): QueryDeviceStatisticsResponse?
    {
        return client.getAcsResponse(QueryDeviceStatisticsRequest().apply { productKey = pk })
    }
}
